﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace UIConsole
{
    class Program
    {
        const string LOCATION_SHOW = @"
================================
{0}
--------------------------------
{1}
--------------------------------
{2}
--------------------------------";
        static void Main(string[] args)
        {
            var dal = new Dal.TheGoldAventure();
            var allLocations = dal.GetLocations();
            var location = allLocations.First();

            while (true)
            {

                var cmds = 
                    Enumerable.Range(0, location.Commands.Count())
                    .Select(i => (i + 1).ToString() + ": " + location.Commands[i].CommandText)
                    .ToArray();

                var locationText = string.Format(
                    LOCATION_SHOW,
                    location.Title,
                    location.Body.Trim().WordWrap(32),
                    string.Join(Environment.NewLine, cmds)
                    );
                Console.WriteLine(locationText);

                var locationNotChanged = true;
                while (locationNotChanged)
                {
                    var key = Console.ReadKey();
                    int intKey;
                    if (int.TryParse(key.KeyChar.ToString(), out intKey) 
                        && intKey > 0 && location.Commands.Count >= intKey)
                    {
                        var destId = location.Commands[intKey - 1].GoToDestinationId;
                        location = allLocations.Find(x => x.Id == destId);
                        locationNotChanged = false;
                        Console.WriteLine();
                    }
                    else
                    {
                        Console.WriteLine(" - Try Again!");
                    }
                }

            }

        }
    }

    //http://www.blackbeltcoder.com/Articles/strings/implementing-word-wrap-in-email-messages
    public static class StringExtensions
    {
        /// <summary>
        /// Word wraps the given text to fit within the specified width.
        /// </summary>
        /// <param name="text">Text to be word wrapped</param>
        /// <param name="width">Width, in characters, to which the text
        /// should be word wrapped</param>
        /// <returns>The modified text</returns>
        public static string WordWrap(this string text, int width)
        {
            int pos, next;
            StringBuilder sb = new StringBuilder();

            // Lucidity check
            if (width < 1)
                return text;

            // Parse each line of text
            for (pos = 0; pos < text.Length; pos = next)
            {
                // Find end of line
                int eol = text.IndexOf(Environment.NewLine, pos);
                if (eol == -1)
                    next = eol = text.Length;
                else
                    next = eol + Environment.NewLine.Length;

                // Copy this line of text, breaking into smaller lines as needed
                if (eol > pos)
                {
                    do
                    {
                        int len = eol - pos;
                        if (len > width)
                            len = BreakLine(text, pos, width);
                        sb.Append(text, pos, len);
                        sb.Append(Environment.NewLine);

                        // Trim whitespace following break
                        pos += len;
                        while (pos < eol && Char.IsWhiteSpace(text[pos]))
                            pos++;
                    } while (eol > pos);
                }
                else sb.Append(Environment.NewLine); // Empty line
            }
            return sb.ToString();
        }

        /// <summary>
        /// Locates position to break the given line so as to avoid
        /// breaking words.
        /// </summary>
        /// <param name="text">String that contains line of text</param>
        /// <param name="pos">Index where line of text starts</param>
        /// <param name="max">Maximum line length</param>
        /// <returns>The modified line length</returns>
        private static int BreakLine(string text, int pos, int max)
        {
            // Find last whitespace in line
            int i = max;
            while (i >= 0 && !Char.IsWhiteSpace(text[pos + i]))
                i--;

            // If no whitespace found, break at maximum length
            if (i < 0)
                return max;

            // Find start of whitespace
            while (i >= 0 && Char.IsWhiteSpace(text[pos + i]))
                i--;

            // Return length of text before whitespace
            return i + 1;
        }
    }
}
